/*
 * Class NetReader
 * Created on 13/04/2005
 * @author Marcelo G. Armentano
 */
package pATT.bNEdit.base;

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.io.Serializable;
import java.util.Vector;

/**
 *
 * Open an Hugin .net file
 *
 */
public class NetReader implements Serializable{

    /**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	private RedBayes bayesNet;

    /**
     * @param bayesNet The bayesian network
     */
    public NetReader(RedBayes bayesNet) {
        this.bayesNet = bayesNet;
    }

    /**
     * @return Returns the bayesNet.
     */
    public RedBayes getBayesNet() {
        return bayesNet;
    }

    /**
     * Loads fileName into the current bayesian network
     * @param fileName The path of the file to load
     */
    public void load(String fileName){
        try{
            BufferedReader reader = new BufferedReader(new FileReader(fileName));
            String s = "";
            boolean seguir=true;
            //Looking for the name of the net
            while(seguir){
                s=reader.readLine();
                if(s==null)
                    seguir=false;
                else{
                    //s=s + t;
                    if (s.indexOf("class")!=-1){
                        String nombre = s.substring(s.indexOf("class")+6);
                        getBayesNet().setNombre(nombre);
                        seguir=false;
                    }
                }
            };
            seguir = true;
            //Loading nodes
            while(seguir){
                if(s==null || s.indexOf("potential")!=-1)
                    seguir=false;
                else{
                    if (s.indexOf("node ")!=-1){
                        loadNode(reader, s);
                    }
                    s=reader.readLine();
                }

            };
            //Loading probabilities
            seguir = true;
            while(seguir){

                if(s==null)
                    seguir=false;
                else{
                    if (s.indexOf("potential")!=-1){
                        loadArc(reader, s);
                    }
                }
                s=reader.readLine();
            };
        }catch(IOException e){
            System.out.println("Error leyendo archivo: " + e.getMessage());
//            System.exit(0);
        }
    }

    @SuppressWarnings("unchecked")
	public void loadNode(BufferedReader reader, String s){
        String nodeName = s.substring(s.indexOf("node")+5);
        getBayesNet().addNodo(nodeName);
        boolean lookingForPosition = true;
        boolean lookingForStates = true;
        boolean goOn = true;
        while((lookingForPosition || lookingForStates) && goOn){
            try {
                s = reader.readLine();
                if(s==null || s.indexOf("node")!=-1)
                    goOn=false;
                else{
                    if (s.indexOf("position")!=-1){
                        String position;
                        position = s.substring(s.indexOf("(")+1, s.indexOf(")"));
                        String posXs = position.substring(0,position.indexOf(" "));
                        String posYs = position.substring(position.indexOf(" ")+1);
                        int posX = Integer.parseInt(posXs.replaceAll(" ",""));
                        int posY = Integer.parseInt(posYs.replaceAll(" ",""));
                        getBayesNet().getNodo(nodeName).setPosicion(posX,posY);
                        lookingForPosition = false;
                    }
                    else if (s.indexOf("states")!=-1){
                        Vector states=new Vector();
                        String statesStr;
                        statesStr = s.substring(s.indexOf("(")+1,
                                s.indexOf(")"));
                        String[] estados = statesStr.split(" ");
                        for (int i = 0; i < estados.length; i++) {
                            String estado = estados[i].replaceAll("\"", "");
                            states.add(estado);
                        }
                        getBayesNet().getNodo(nodeName).setEstados(states);
                        lookingForStates = false;
                    }
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * Loads arcs between parents and its node, with corresponding probabilities
     * @param reader The FileReader
     * @param s The current line
     */
    private void loadArc(BufferedReader reader, String s){
        String involvedNodes = s.substring(s.indexOf("(")+1, s.indexOf(")"));
        String sonNode = "";
        String parents = "";
        if (involvedNodes.indexOf("|")!=-1){//Si tiene padres
          parents = involvedNodes.substring(involvedNodes.indexOf("|")+2);
          sonNode = involvedNodes.substring(0, involvedNodes.indexOf("|")-1);
    	}
        else sonNode = involvedNodes;
        if (parents.length()>0) {
            String[] parentNodes = parents.split(" ");
	        for (int i = 0; i < parentNodes.length; i++) {
	            String parent = parentNodes[i];
	            getBayesNet().addArco(parent,sonNode);
	        }
        }
        try {
            reader.readLine();//Paso la llave
        } catch (IOException e1) {
            e1.printStackTrace();
        }

        boolean seguir = true;
        String probabilities = "";
        while(seguir){
            try {
                s = reader.readLine();
                if(s==null || s.indexOf("}")!=-1 || s.indexOf("experience")!=-1)
                    seguir=false;
                else{
                    //s=s + t;
                    probabilities += s.substring(s.lastIndexOf("(")+2, s.indexOf(")"));
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        String[] values_str = probabilities.split(" ");
        int cantValues = values_str.length;
        double[] values=new double[cantValues];
        for(int j=0 ; j < cantValues; j++){
            String valor=values_str[j];
            Double v=new Double(valor);
            values[j]=v.doubleValue();
        }
        Potencial p=getBayesNet().getNodo(sonNode).getProbabilidadOriginal();
        int statesCount=getBayesNet().getNodo(sonNode).getEstados().size();
        int pos=0;
        for(int k=0 ; k < statesCount ; k++ ){
            for(int h= k ; h < cantValues  ; h = h + statesCount ) {
                p.set(pos,values[h]);
                pos++;
            }
        }

    }
}
